package common

import (
	"errors"
	"fmt"
	"github.com/gin-gonic/gin"
	"github.com/go-playground/validator/v10"
	"math/rand"
	"mime/multipart"
	"os"
	"reflect"
	"strings"
	"time"
)
/*
	@Title GetValidMsg
	@Description  根据错误,拿到结构体的错误字段{tag}返回错误给前端.
	@Author zsg   2023-01-12 15:12.
	@Param  err error 错误 | obj any 错误字段的结构体  |  tag string  错误字段结构体的错误提示tag.
	@Return  tagString string  结构体元素里的错误提示.
*/
func GetValidMsg(err error,obj any,tag string)(tagString string){
	if tag==""{
		tag="msg"
	}
	getObj:=reflect.TypeOf(obj)
	//断言错误类型 validator.ValidationErrors,  根据错误拿到对应的字段,如果不是这个类型就是其他错误
	if errs,ok:=err.(validator.ValidationErrors);ok{
		for _,v:=range errs{
			//根据字段获取构体的tag值
			if f,exits:=getObj.Elem().FieldByName(v.Field());exits{
				tagString=f.Tag.Get(tag)
				return tagString
			}
		}
	}
	return err.Error()
}

/*
	@Title PathExists
	@Description  判断文件或文件夹是否存在
	@Author zsg   2023-01-12 17:47.
	@Param  path string 文件或者文件夹路径 .
	@Return  bool 是否存在|  error 错误信息 .
*/
func PathExists(path string) (bool,error) {
	_,err := os.Stat(path)
	if err == nil {
		return true,nil
	}
	if os.IsNotExist(err) {
		return false,nil
	}
	return false,err
}

/*
	@Title FieldUpload
	@Description  文件上传
	@Author zsg   2023-01-12 17:47.
	@Param  files []*multipart.FileHeader 多文件切片 | g *gin.Context  gin框架的上下文
	@Return  msg string 成功与失败的统计| err error 错误信息 .
*/
func FieldUpload(files []*multipart.FileHeader, g *gin.Context) (msg string, err error) {
	//时间 2006-01-02
	timeStr := time.Now().Format("2006-01-02")
	//判断文件路径是否存在,不存在就去创建
	isExist, err := PathExists("resources/upload/" + timeStr)
	if err == nil && isExist == false {
		//创建文件
		if err = os.Mkdir("resources/upload/"+timeStr, os.ModePerm); err != nil {
			err = errors.New("穿件文件路径失败")
			return
		}
	}
	i := 0
	errFile := []string{}
	for _, v := range files {
		//文件名称  原名+时间戳(毫秒)+1000以内的随机数
		fileName := v.Filename
		fileNameArr := strings.Split(fileName, ".")
		formatName := fileNameArr[len(fileNameArr)-1]
		newFileName := fmt.Sprintf("%s%d%d", fileNameArr[0], time.Now().UnixNano(), rand.Intn(1000)) + "." + formatName
		//上传
		if err = g.SaveUploadedFile(v, "resources/upload/"+timeStr+"/"+newFileName); err != nil {
			errFile = append(errFile, fileName)
			continue
		}
		i++
	}
	if len(errFile) > 0 {
		msg = fmt.Sprintf("成功上传%d个文件,%s %d个文件上传失败", i, strings.Join(errFile,"|"),len(errFile))
		return
	}
	msg = fmt.Sprintf("成功上传%d个文件", i)
	return
}










